/**
 * 
 */
package vue.session;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import model.session.CNFUse;
import vue.globalBar.IGBarPreprocessor;

/**
 * A {@link IGCNFUse} is a block related to a cnf use in a session, it is somehow related to
 * {@link CNFUse}.
 * 
 * @author GRONOWSKI Stephane svan001@aol.com
 * 
 *         igsat 2010
 * 
 */
public class IGCNFUse extends IGBlock {

	private CNFUse								cnfuse		= null;
	private Set<IGSolverBlock>					solvers		= new HashSet<IGSolverBlock>();
	private Map<IGPreprocessorBlock, IGCNFUse>	preprocs	= new HashMap<IGPreprocessorBlock, IGCNFUse>();

	// private boolean first = false;


	/**
	 * Create an {@link IGCNFUse} .
	 * 
	 * @param cnf
	 *            the {@link CNFUse} associate
	 */
	public IGCNFUse(CNFUse cnf) {
		cnfuse = cnf;
	}

	/**
	 * Create an {@link IGCNFUse} .
	 * 
	 * @param cnf
	 *            the {@link CNFUse} associate@param cnf
	 * @param listeners
	 *            a set of {@link IIGModificationListener}
	 */
	public IGCNFUse(CNFUse cnf, Set<IIGModificationListener> listeners) {
		super(listeners);

		cnfuse = cnf;
	}

	/**
	 * Return the {@link CNFUse} associate.
	 * 
	 * @return the {@link CNFUse} associate.
	 */
	public CNFUse getCnfuse() {
		return cnfuse;
	}

	/**
	 * set the {@link CNFUse} associate.
	 * 
	 * @param cnfuse
	 *            the {@link CNFUse} to set
	 */
	public void setCnfuse(CNFUse cnfuse) {
		this.cnfuse = cnfuse;
	}

	/**
	 * Return the solvers from the cnf.
	 * 
	 * @return the solvers from the cnf.
	 */
	public Set<IGSolverBlock> getSolvers() {
		return solvers;
	}

	/**
	 * Add a solver to the {@link IGCNFUse}.
	 * 
	 * @param solver
	 *            the solvers to set
	 */
	public void addSolver(IGSolverBlock solver) {
		solvers.add(solver);
		addSecond(solver);
		solver.addSecond(this);
	}

	/**
	 * remove a solver to the {@link IGCNFUse}.
	 * 
	 * @param solver
	 *            the solvers to remove
	 */
	public void removeSolver(IGSolverBlock solver) {
		solvers.remove(solver);
		solver.removesecond(this);
		removesecond(solver);
	}

	/**
	 * Return the {@link IGBarPreprocessor} from the cnf.
	 * 
	 * @return the {@link IGBarPreprocessor} from the cnf.
	 */
	public Map<IGPreprocessorBlock, IGCNFUse> getPreprocs() {
		return preprocs;
	}

	/**
	 * Add a {@link IGPreprocessorBlock} to the {@link IGCNFUse}.
	 * 
	 * @param preproc
	 *            the {@link IGPreprocessorBlock} to add
	 * @param cnfuse
	 *            the {@link IGCNFUse} result of the preprocessor execution
	 */
	public void addPreproc(IGPreprocessorBlock preproc, IGCNFUse cnfuse) {
		preprocs.put(preproc, cnfuse);
		addSecond(preproc);
		preproc.addSecond(this);
		if (cnfuse != null)
			preproc.addSecond(cnfuse);

	}

	/**
	 * Remove a {@link IGPreprocessorBlock} to the {@link IGCNFUse}.
	 * 
	 * @param preproc
	 *            the {@link IGPreprocessorBlock} to add
	 * @return the {@link IGCNFUse} result of the preprocessor execution
	 */
	public IGCNFUse removePreproc(IGPreprocessorBlock preproc) {
		preproc.removesecond(this);
		preproc.removesecond(preprocs.get(preproc));
		removesecond(preproc);
		return preprocs.remove(preproc);
	}

	/**
	 * Return if the cnf is the first.
	 * 
	 * @return if the cnf is the first
	 */
	public boolean getFirst() {
		// System.out.println("get first: " + cnfuse.getFirst() + " cnf: " + cnfuse);
		return (cnfuse.getFirst() == cnfuse);
	}


}
